using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Collections;

using Velocity = NVelocity.App.Velocity;
using VelocityContext = NVelocity.VelocityContext;
using Template = NVelocity.Template;
using ParseErrorException = NVelocity.Exception.ParseErrorException;
using ResourceNotFoundException = NVelocity.Exception.ResourceNotFoundException;
using Castle.Components.Common.TemplateEngine;
using Castle.Components.Common.TemplateEngine.NVelocityTemplateEngine;
using System.Reflection;
using NVelocityTemplateEngine;
using NVelocityTemplateEngine.Interfaces;
using R2ML;

namespace EventAbstractionAPI.CodeGenerator
{
    public class EventLoopBuilder
    {

        public EventLoopBuilder()
        {
        }

        internal string GenerateCode()
        {
            GetEventsFromR2ML();

            string assemblyName = Assembly.GetExecutingAssembly().GetName().Name;
            string theNamespace = "EventAbstractionAPI.CodeGenerator";

            INVelocityEngine embeddedEngine = NVelocityEngineFactory.CreateNVelocityAssemblyEngine(assemblyName, theNamespace, true);


            IDictionary context = new Hashtable();

            context.Add("namespace", "WindowsApplication");
            context.Add("events", _eventlist);
            context.Add("rulelist", _ruleeventlist);
            context.Add("actionlist", _actionlist);

            String s = embeddedEngine.Process(context, "Resources.CodeLoop.vm");

            return s;
        }

        private void GetEventsFromR2ML()
        {
            if (R2ML.RuleFactory.Instance.Initialized())
            {
                //rules are loaded; get the action code.
                foreach (ReactionRule rr in RuleFactory.Instance.ruleBase.ruleSet.reactionRuleList)
                {
                    //TODO: ############## Make the eventlist a hashdictionary so that repetitions are removed.#############
                    _eventlist.Add(rr.triggeringEvent.messageEventExpression.eventType);
                    _ruleeventlist.Add(rr.triggeringEvent.messageEventExpression.eventType);
                    _actionlist.Add(rr.triggeringEvent.messageEventExpression.eventType,rr.Documentation.SourceCode.MethodInstance.Name);
                }
            }
            else
            {
                throw new Exception("load the r2ml rule list first");
            }
        }

        #region Member Variables

        ArrayList _eventlist = new ArrayList();
        ArrayList _ruleeventlist = new ArrayList();
        IDictionary _actionlist = new Hashtable(); 

        #endregion
    }
}




